When a new computer processor is developed, existing applications or programs, herein “applications,” which executed properly on a prior computer processor may not execute properly on the new computer processor. These old, or in other words non-native applications, are typically “ported,” i.e., rewritten or translated, to run on the new processor. Usually, until an application is ported, it is unable to take advantage of any beneficial features in the new processor. Depending on the amount of effort required to port the application, there may be a substantial amount of time lost before an application can benefit from the new processor.
Typically a computer system having the new computer processor will have a separate environment for running “old” applications written for the old processor. This environment is called a “compatibility box.” In these systems there is substantially no interaction between the compatibility box and the new processor environment, otherwise known as the “native” environment. Thus “old” applications cannot take advantage of performance benefits and other advantageous features available in the native environment. It is often difficult to execute arbitrary “old” code from the native environment as well.
Some computer systems have emulators, which permit the computer system to execute code which is written for a processor other than the processor which is native to the computer system. Typically, these emulators assume a single runtime environment, that is to say they assume that the conventions for invoking program procedures and performing stack manipulations are common to both the native and non-native or emulated code. These emulators typically just alter the instructions set and are not structured to handle two different types of program object code which have different routine calling and stack manipulation conventions.
However, the process to embed the object codes in a new source code is quite labor-intensive. For instance, the assembly instructions executable by Motorola's 680×0 microprocessor in a Macintosh computer cannot be executed directly by a PowerPC processor of a PowerPC computer. FIG. 9A shows an example of assembly instructions written in Motorola's 680×0 assembly language. In order for the codes being able to execute in PowerPC computer, the assembly instructions may required to be translated into PowerPC instructions or into a language which can be compiled into PowerPC instructions (e.g., C language such as one shown in FIG. 9B). In some cases, it is impractical to rewrite the routine in C; for example, function SETSTATUSREGISTER may not possibly be implemented, because there is no direct analogy in the PowerPC instruction set as to what is being done. Therefore, it is necessary to embed the object code of the routine in the source code of the PowerPC computer, in order to allow the emulator to perform the execution.
One method to embed an object code, such as the object code of the routine of FIG. 9A, in a source code of PowerPC is to compile the routine with a 680×0 compatible assembler, create corresponding code resources for the routine in a resource file and calculate an offset of the routine, and then place this code in a resource where it can be loaded later. At runtime, the resource would be loaded in memory, the entry point of the routine would be calculated, and the routine would be called by telling the emulator to begin execution of this calculated code address.
FIG. 1 shows a conventional method of embedding a Motorola 680×0 (68k) assembly object code in the source code. When the 68k assembly codes are received 101, the 68k codes are assembled with a Motorola 68k assembler. An object file (*.o) is created 102. Next the code resources are generated 103 based on the object file, and the code resources are manually converted into a format compatible with the new system. At runtime, the entry point of the routine is retrieved 104 from the code resources, and error checking is performed 105. Typically the entry point is retrieved through an application programming interface (API) GetResource( ). If there is no error, the routine is executed 106 through an API CallUniversalProc( ), otherwise an error message is generated 107 through an exception.
There are some disadvantages of this method. One of the disadvantages is that the resource may not be loaded successfully, due to numerous reasons (e.g., not enough memory, etc.); another disadvantage is that the entry point may not be valid (e.g., nil pointer). Thus there is no guarantee of having the routine available at runtime. In addition, this process involves intense manual calculations, which post inconvenience and poor efficiency to the software development. Therefore, a method to automatically embed an object code in a source code is highly desired.